#pragma once
#include <functional>
#include <atomic>
#include <unistd.h>
#include <string.h>
#include <vector>
#include <chrono>

#include "log/log.h"
// #include "utils.h"
#include "mpp/rk_mpi.h"
// #include "mpp_log.h"
#include "mpp/mpp_mem.h"
#include "mpp/mpp_env.h"
// #include "mpp_time.h"
#include "mpp/mpp_common.h"
#include "mpp/mpp_frame.h"

#include "clocker/clocker.h"

class SmartMppDecoder {
public:
    SmartMppDecoder() {}
	SmartMppDecoder(MppCodingType type) {
        init(type);
    }

	~SmartMppDecoder() {
        deinit();
    }

	int init(MppCodingType type);
	int deinit();
    int sync_decoding(uint8_t* pkt_buf, uint32_t pkt_len, std::function<void(uint8_t* frm_buf, uint32_t frm_len)> callback);
    int put_packet(uint8_t *buf, uint32_t len);
    int loop_get_frame(std::function<void(std::vector<uint8_t>&)> callback);
    int loop_get_frame(std::function<void(uint8_t*, uint32_t)> callback);
    int loop_get_frame_raw(std::function<void(uint8_t*, uint32_t)> callback);
    int stop();

private:
    typedef struct {
        MppCtx ctx;
        MppApi* mpi;

        MppBufferGroup frm_grp;
        MppPacket packet;
        MppFrame frame;

        // 初始化配置参数 
        MppCodingType type;
        uint32_t need_split;

        // 过程参数
        RK_S32 frame_count;
        size_t max_usage;

        uint32_t width;
        uint32_t height;
        uint32_t hor_stride;
        uint32_t ver_stride;
        uint32_t frame_buf_size;
        MppFrameFormat fmt;

        uint32_t error_num;
        uint32_t error_try_num;
    } dec_ctx_t;

    const int MAX_DEC_ERROR_NUM{30};  // 错误帧数超过当前值则重新初始化MPP
    const int MAX_DEC_ERROR_TRY_NUM{5};  // 超过当前次数未能成功发送，则丢弃当前帧

    dec_ctx_t m_dec_ctx{0};
    std::atomic_bool m_loop_run{false};
};
